/*
 *  Copyright 2012 Anton Van Zyl. http://code.google.com/p/java-swiss-knife/
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package com.knife.web.net;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;


/**
 * This is a utility class that will send a file to download by the client.
 * 
 * <br/>
 * <br/>
 * Please visit <a
 * href="http://code.google.com/p/java-swiss-knife/">Java-Swiss-Knife</a> and
 * comment, rate, contribute or raise a issue/enhancement for my library. <br/>
 * 
 * @author Anton Van Zyl
 * 
 */
public final class FileDownloadUtil {

	/**
	 * This will take the file and send it to the clients browser to be
	 * downloaded by the client.<br/>
	 * ContentType and contentDisposition is important, choosing the correct
	 * contentType will enable the client to open the document in a native
	 * application that use the MIME type, and using content disposition, the
	 * client will be able to view the document on a 3rd party app or inline
	 * with their browser, depending on what applications the client has
	 * installed.
	 * 
	 * @param fileToSend 
	 * @param contentType
	 * @param contentDisposition
	 * @param deleteFileAfterDownload
	 * @param response
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	public static void sendFileToClient(File fileToSend, ContentType contentType, ContentDisposition contentDisposition, boolean deleteFileAfterDownload,
			HttpServletResponse response) throws IOException, FileNotFoundException {

		ServletOutputStream stream = null;
		BufferedInputStream filein = null;
		try {
			System.out.println("com.knife.web.net.sendFileToClient File download beginning.... [FileName=" + fileToSend.getName() + ";contentType=" + contentType + ";contentDisposition="
					+ contentDisposition + ";]");
			response.setContentType(contentType.getTypeString());

			// IE8 Bug workaround (IE8 does not allow download of non cache
			// files over a https connection)
			response.setHeader("Pragma", "max-age=10");
			response.setHeader("Cache-control", "max-age=10");

			response.setHeader("Content-Disposition", contentDisposition.getValue() + "; filename=\"" + fileToSend.getName() + "\"");
			response.setContentLength((int) (fileToSend.length()));

			stream = response.getOutputStream();
			filein = new BufferedInputStream(new FileInputStream(fileToSend.getPath()));
			int data;
			while ((data = filein.read()) != -1) {
				stream.write(data);
			}
			stream.close();
		} catch (FileNotFoundException e) {
			System.err.println("com.knife.web.net.sendFileToClient File download Failed - " + e.getMessage());
			response.setContentType("text/html");
			response.setHeader("Content-Disposition", "");
			throw new FileNotFoundException(e.getMessage());
		} finally {
			if (filein != null) {
				filein.close();
			}
			if (stream != null) {
				stream.close();
			}
			if (deleteFileAfterDownload && fileToSend.exists()) {
				boolean deleteFile = fileToSend.delete();
				if (deleteFile == false) {
					System.err.println("com.knife.web.net.sendFileToClient Failed to delete file [" + fileToSend.getName() + "]");
				}
			}
			response.flushBuffer();
		}
		System.out.println("com.knife.web.net.sendFileToClient File downloaded successfully [" + fileToSend.getName() + "]");
	}

}
